package com.xbell.dahua.demo.camera;

import com.netsdk.lib.NetSDKLib;
import com.netsdk.lib.ToolKits;
import com.xbell.dahua.demo.camera.dahua.*;
import lombok.extern.slf4j.Slf4j;

import static com.xbell.dahua.demo.camera.dahua.LoginModule.M_DEVICE_INFO_EX;

/**
 * 大华网络摄像头实现
 */
@Slf4j
public class DahuaWebCamera implements WebCamera {

    private static final String ip = "112.28.138.6";
    private static final int port = 37777;
    private static final String username = "admin";
    private static final String password = "zyhl_admin_2020";

    private NetSDKLib.LLong loginHandle;

    @Override
    public void init() {
        DisConnect disConnect = new DisConnect();
        HaveReConnect haveReConnect = new HaveReConnect();
        LoginModule.init(disConnect, haveReConnect);
        // 登录设备
        //        if (loginHandle.longValue() != 0) {
//            // 2. 登录成功
//            log.info("登录成功");
//        }
        this.loginHandle = login(ip, port, username, password);
        log.info("login handle: {}", loginHandle.longValue());

//        // 订阅人数回调
//        NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM videoStatIn = new
//                NetSDKLib.NET_IN_ATTACH_VIDEOSTAT_SUM();
//        videoStatIn.nChannel = 0;
//        // 创建 VideoStatSumCallback 回调
//        videoStatIn.cbVideoStatSum = VideoStatSumCallback.getInstance();
//        NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM videoStatOut = new
//                NetSDKLib.NET_OUT_ATTACH_VIDEOSTAT_SUM();
//        NetSDKLib.LLong videoStatHandle = NetSDKLib.NETSDK_INSTANCE.CLIENT_AttachVideoStatSummary(loginHandle,
//                videoStatIn, videoStatOut, 5000);
//
//        if (videoStatHandle.longValue() == 0) {
//            log.error("Attach Failed!LastError: {}",
//                    NetSDKLib.NETSDK_INSTANCE.CLIENT_GetLastError());
//            // 订阅失败输出
//        } else {
//            // 订阅成功
//            log.info("订阅人数统计成功");
//        }
    }

    @Override
    public void destroy() {
        NetSDKLib.NETSDK_INSTANCE.CLIENT_StopRealPlayEx(loginHandle);
        LoginModule.logout(loginHandle);
    }

    @Override
    public String realPlay() {
        NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE inParam = new NetSDKLib.NET_IN_REALPLAY_BY_DATA_TYPE();
        NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE outParam = new NetSDKLib.NET_OUT_REALPLAY_BY_DATA_TYPE();
        inParam.nChannelID = 0;
        inParam.rType = NetSDKLib.NET_RealPlayType.NET_RType_Realplay;
//        inParam.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_FLV_STREAM;
        inParam.emDataType = NetSDKLib.EM_REAL_DATA_TYPE.EM_REAL_DATA_TYPE_TS;

        NetSDKLib.LLong lRealHandle = NetSDKLib.NETSDK_INSTANCE.CLIENT_RealPlayByDataType(loginHandle,
                inParam, outParam, 3000);

        if (lRealHandle.longValue() != 0) {
            log.info("request real play succeed");
            Boolean code = NetSDKLib.NETSDK_INSTANCE.CLIENT_SetRealDataCallBackEx(lRealHandle,
                    CbfRealDataCallBackEx.getInstance(), null,
                    0x00000001);
            log.info("set real data callback result code: {} LastError: {}", code, NetSDKLib.NETSDK_INSTANCE.CLIENT_GetLastError());
        } else {
            log.error("request real play failed, last error: {}", NetSDKLib.NETSDK_INSTANCE.CLIENT_GetLastError());
        }
        return loginHandle.longValue() + ".ts";
    }

    @Override
    public void registerEvent() {

    }

    public NetSDKLib.LLong login(String ip, int port, String user, String pwd) {
        // 入参
        NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstInParam.nPort = port;
        pstInParam.szIP = ip.getBytes();
        pstInParam.szUserName = user.getBytes();
        pstInParam.szPassword = pwd.getBytes();
        // 出参
        NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY();
        pstOutParam.stuDeviceInfo = M_DEVICE_INFO_EX;
        NetSDKLib.LLong loginHandle = NetSDKLib.NETSDK_INSTANCE.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam);
        if (loginHandle.longValue() == 0) {
            log.error("Login failed IP:{}, Port:{}, Msg:{}", ip, port, ToolKits.getErrorCodePrint());
            throw new IllegalStateException("Login failed IP:" + ip + ", Port:" + port);
        } else {
            log.info("Login succeed IP:{}, Port:{}", ip, port);
        }
        return loginHandle;
    }

}
